import { Pressable, StyleSheet, Text, View, ScrollView, Image, ImageBackground, TouchableOpacity } from 'react-native';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useKeepAwake } from '@sayem314/react-native-keep-awake';
import { useNavigation } from '@react-navigation/native';
import RNFS from 'react-native-fs2';
import { checkVersion, getDeviceUploadUrl, updateComplete } from '~/api/deviceApi';
import { observer, deviceStore } from '~/store';
import { NavBarHeader, ChinaProGressModal } from '~/components';
import { isIos, px2dp, scale } from '~/utils/px2dp';
import {
    intToByte,
    send_data,
    bytetoint,
    bytetochar,
    OTA_CMD_NVDS_TYPE,
    OTA_CMD_PAGE_ERASE,
    OTA_CMD_GET_STR_BASE,
    OTA_CMD_WRITE_DATA,
    OTA_CMD_REBOOT,
} from '~/utils/ble/chinaUpgrade';
import BleConnection from '~/utils/ble/connect';
import BleModule from '~/utils/ble/bleModule';
var Buffer = require('buffer').Buffer;

const Bleconnect = BleConnection.getInstance();
const bleModule = BleModule.getInstance();
const ExternalDirectoryPath = isIos() ? RNFS.LibraryDirectoryPath : RNFS.ExternalDirectoryPath;
const DEVICE_8010 = 0;
const DEVICE_8010H = 1;

export default observer(() => {
    useKeepAwake();
    const navigation: any = useNavigation();
    const { t } = useTranslation();
    const { connectDeviceInfo, device } = deviceStore;
    const { device_code = '', id = '', device_sn = '' } = device.connectDevice;
    const [isUpgrade, setIsUpgrade] = useState(false);
    const [descript, setDescript] = useState([]);
    const [version_sn, setVersion_sn] = useState('');
    const [url, setUrl] = useState('');
    const isNewDevice = (version) => {
        const dotCount = (version.match(/\./g) || []).length;
        return dotCount === 3;
    };
    const checkDevice = async () => {
        try {
            const res = await checkVersion({
                firmware_code: connectDeviceInfo.productModle,
                version_sn: connectDeviceInfo.firmwareVersion,
                device_sn,
            });
            if (parseInt(res.status) === 1) {
                setIsUpgrade(true);
                const { node, version_sn, firmware_code } = res.data;
                const list = node.split(/[\n]/);
                setDescript(list);
                setVersion_sn(version_sn);
                getDeviceUploadUrl({ firmware_code, version_sn }).then(async (result) => {
                    if (parseInt(result.status) == 1) {
                        const toLoadPath = `${ExternalDirectoryPath}/a.bin`;
                        let url = isNewDevice(connectDeviceInfo.firmwareVersion)
                            ? result.data.new_url
                            : result.data.url;
                        RNFS.downloadFile({
                            fromUrl: url,
                            toFile: toLoadPath,
                            progressDivider: 5,
                            begin: (res) => console.log('begin', res),
                            progress: (res) => console.log('progress', res),
                        })
                            .promise.then(() => {
                                setUrl(toLoadPath);
                            })
                            .catch((err) => {
                                console.error('解析文件失败', err);
                                setIsUpgrade(false);
                            });
                    }
                });
            } else {
                setIsUpgrade(false);
            }
        } catch (error) {
            console.log('解析错误解析错误', error);
        }
    };

    const [visible, setVisible] = useState(false);
    const [progress, setProgress] = useState(0);
    // -----------开始升级--------------
    const onPress = async () => {
        if (connectDeviceInfo.eq <= 20) {
            Toast.show({ content: t('UpdateDfuDevice.t13') });
            return;
        }
        setVisible(true);
        let files: any = await readFile();
        let packageSize;
        let deviceType = 0;
        let size = 0;
        await Bleconnect.startNotification_china();
        let cmd_init = send_data(OTA_CMD_NVDS_TYPE, 0, 0, 0);
        const init_value = await writeData_china(cmd_init);
        if (isIos()) {
            size = 185;
        } else {
            if ((bytetochar(init_value) & 0x10) == 0) {
                deviceType = DEVICE_8010;
                size = await Bleconnect.requesMtu(247);
            } else {
                deviceType = DEVICE_8010H;
                size = await Bleconnect.requesMtu(512);
            }
        }
        packageSize = size - 3 - 9;
        //获取起始地址
        let cmd_addr = send_data(OTA_CMD_GET_STR_BASE, 0, 0, 0);
        const addr_value = await writeData_china(cmd_addr);
        await page_erase(bytetoint(addr_value), files.length);
        let i = 0;
        let addr = bytetoint(addr_value);
        while (i < files.length) {
            let inputBuffer = files.slice(i, i + packageSize);
            i += packageSize;
            let write = send_data(OTA_CMD_WRITE_DATA, addr, inputBuffer, inputBuffer.length);
            let p = Math.floor((i / files.length) * 100);
            setProgress(p);
            let temp = await writeData_china(write, 0);
            if (!Array.isArray(temp) || temp.length !== 10) {
                setVisible(false);
                Toast.show({ content: t('UpdateDfuDevice.t15') });
                deviceStore.disConnectble();
                return false;
            }
            addr += packageSize;
        }
        let reboot = send_data(OTA_CMD_REBOOT, 0, 0, 0);
        await writeData_china(reboot);
        setVisible(false);
        Toast.show({ content: t('UpdateDfuDevice.t14') });
        updateComplete({ version_sn, armarium_device_chang: connectDeviceInfo.factorySerialNumber });
        deviceStore.disConnectble();
        setTimeout(() => {
            navigation.navigate('Main');
        }, 500);
    };
    const writeData_china = async (data, time = 100) => {
        await Bleconnect.write_china(data);
        let recvValue = await bleModule.getValue('recvValue', time);
        return recvValue;
    };
    // ----------- 开始读取文件 -----------
    const Hexstring2btye = (str) => {
        let pos = 0;
        let len = str.length;
        if (len % 2 != 0) {
            return null;
        }
        len /= 2;
        let hexA = new Array();
        for (let i = 0; i < len; i++) {
            let s = str.substr(pos, 2);
            let v = intToByte(parseInt(s, 16));
            hexA.push(v);
            pos += 2;
        }
        return hexA;
    };

    const readFile = async () => {
        try {
            const contents = await RNFS.readFile(url, 'base64');
            let buf = Buffer.from(contents, 'base64');
            let bytes = Hexstring2btye(buf.toString('hex'));
            return bytes;
        } catch (e) {
            console.error('读取文件失败>>>>>>>>', e);
            setVisible(false);
        }
    };
    const page_erase = async (addr, length) => {
        let count = Math.ceil(length / 0x1000);
        for (let i = 0; i < count; i++) {
            let cmd = send_data(OTA_CMD_PAGE_ERASE, addr, 0, 0);
            const value = await writeData_china(cmd, 0);
            addr += 0x1000;
        }
        return 0;
    };
    useEffect(() => {
        checkDevice();
    }, []);
    return (
        <View style={styles.container}>
            <NavBarHeader
                title={t('UpdateDfuDevice.title')}
                rightComponent={
                    <Pressable
                        style={{ marginRight: px2dp(32) }}
                        onPress={() => navigation.navigate('UpdateDeviceLog')}>
                        <Text>{t('UpdateDfuDevice.t1')}</Text>
                    </Pressable>
                }
            />
            <ScrollView contentContainerStyle={styles.contentStyle} showsVerticalScrollIndicator={false}>
                <ImageBackground
                    source={require('~/assets/deviceTools/upgradeBg.png')}
                    style={styles.imgBg}
                    resizeMode={'contain'}>
                    <Image
                        source={require('~/assets/deviceTools/upgradeRocket.png')}
                        resizeMode={'contain'}
                        style={styles.imgLogo}
                    />
                    <View>
                        <Text style={styles.txt}>{t('UpdateDfuDevice.t2')}</Text>
                        <Text style={styles.txt}>{t('UpdateDfuDevice.t3')}</Text>
                    </View>
                </ImageBackground>
                <View style={styles.card}>
                    <View style={[styles.row]}>
                        <Image
                            style={styles.deviceMenues}
                            source={{
                                uri:
                                    connectDeviceInfo.productModle == 'HA05AW'
                                        ? 'https://bjy-dev.oss-cn-shenzhen.aliyuncs.com/xcx/images/typeWatch.png'
                                        : connectDeviceInfo.productModle == 'HA01Y' ||
                                          connectDeviceInfo.productModle == 'HA01YT' ||
                                          connectDeviceInfo.productModle == 'HA01YZ' ||
                                          connectDeviceInfo.productModle == 'HA01YW'
                                        ? 'https://bjy-dev.oss-cn-shenzhen.aliyuncs.com/xcx/images/typeWristband.png'
                                        : connectDeviceInfo.productModle == 'HA06X'
                                        ? 'https://bjy-dev.oss-cn-shenzhen.aliyuncs.com/xcx/images/type06X.png'
                                        : 'https://bjy-dev.oss-cn-shenzhen.aliyuncs.com/xcx/images/type01CW.png',
                            }}
                        />
                        <Text style={styles.t1}>
                            {t('UpdateDfuDevice.t4')}
                            <Text style={styles.version}>{connectDeviceInfo.firmwareVersion}</Text>
                        </Text>
                    </View>
                    <View style={styles.line}></View>
                    {isUpgrade ? (
                        <View style={{ alignSelf: 'center' }}>
                            <View style={[styles.row]}>
                                <Text style={styles.versionSn}>
                                    {t('UpdateDfuDevice.t5')}
                                    {version_sn}
                                </Text>
                                <Image
                                    style={styles.newIcons}
                                    resizeMode="contain"
                                    source={{ uri: 'https://bjy-dev.oss-cn-shenzhen.aliyuncs.com/xcx/images/new.png' }}
                                />
                            </View>
                            <Text style={styles.tips}>{t('UpdateDfuDevice.t6')}</Text>
                            {descript.map((item: any, index) => {
                                return (
                                    <Text style={styles.content_txt} key={index}>{`${index + 1}.${item.trim()}`}</Text>
                                );
                            })}
                            <TouchableOpacity style={[styles.bt, styles.row]} onPress={onPress}>
                                <Text style={styles.bt_text}>{t('UpdateDfuDevice.t7')}</Text>
                            </TouchableOpacity>
                        </View>
                    ) : (
                        <Text style={styles.empity}>{t('UpdateDfuDevice.t8')}</Text>
                    )}
                </View>
                {/* <View style={styles.tipsContent}>
                    <Text style={styles.t2}>{t('UpdateDfuDevice.t9')}</Text>
                    <Text style={styles.t2}>{t('UpdateDfuDevice.t10')}</Text>
                    <Text style={styles.t2}>{t('UpdateDfuDevice.t11')}</Text>
                </View> */}
            </ScrollView>
            <ChinaProGressModal visible={visible} progress={progress} />
        </View>
    );
});

const styles = StyleSheet.create({
    row: {
        flexDirection: 'row',
        alignItems: 'center',
    },
    container: {
        flex: 1,
    },
    contentStyle: {
        flexGrow: 1,
        paddingBottom: '20%',
    },
    imgBg: {
        height: px2dp(320),
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        marginTop: px2dp(30),
        elevation: 2,
        shadowColor: 'black',
        shadowOffset: { width: 2, height: 2 },
        shadowOpacity: 0.2,
        shadowRadius: 2,
    },
    imgLogo: {
        height: px2dp(164),
        width: px2dp(110),
        shadowColor: 'black',
        shadowOffset: { width: 2, height: 2 },
        shadowOpacity: 0.2,
        marginRight: px2dp(24),
    },
    txt: {
        color: '#fff',
        fontSize: scale(40),
        fontWeight: 'bold',
        lineHeight: px2dp(50),
    },
    card: {
        backgroundColor: '#fff',
        padding: px2dp(24),
        margin: px2dp(24),
        borderRadius: px2dp(24),
    },
    deviceMenues: {
        width: px2dp(120),
        height: px2dp(120),
    },
    t1: {
        fontSize: scale(28),
        color: '#191919',
        marginLeft: px2dp(22),
    },
    version: {
        color: 'red',
        fontWeight: 'bold',
        fontSize: scale(32),
    },
    line: {
        height: px2dp(2),
        backgroundColor: '#eee',
        marginVertical: px2dp(32),
    },
    versionSn: {
        fontSize: scale(32),
        fontWeight: 'bold',
        width: '70%',
    },
    newIcons: {
        width: px2dp(160),
        height: px2dp(40),
    },
    tips: {
        marginTop: px2dp(32),
        marginBottom: px2dp(12),
        fontSize: scale(32),
        color: '#a4a4a4',
    },
    content_txt: {
        fontSize: scale(32),
        color: '#111111',
        paddingBottom: px2dp(8),
    },
    bt: {
        backgroundColor: '#61CB8D',
        justifyContent: 'center',
        height: px2dp(80),
        borderRadius: px2dp(50),
        marginTop: px2dp(32),
    },
    bt_text: {
        fontSize: scale(32),
        color: '#fff',
        fontWeight: 'bold',
    },
    tipsContent: {
        margin: px2dp(32),
    },
    t2: {
        fontSize: scale(28),
        lineHeight: px2dp(40),
        marginBottom: px2dp(12),
        color: '#a4a4a4',
    },
    empity: {
        color: '#a4a4a4',
        fontSize: scale(30),
        textAlign: 'center',
    },
});
